# encoding: utf-8
"""
本模块的功能是为了校验代码是否正确，在token之后被调用
检测范围：
1.小括号
2.大括号
3.运算符号
4.字符串符号
5.数组符号
"""

from .compile_share import opers, string
from . import CRE as TRE

from Error.Error import compile_error as send_error


def check_func_symbol(check_code):
    """检查函数符号"""
    if check_code.count("(") != check_code.count(")"):
        send_error("SyntaxError", "couldn't find ')'")


def check_array_symbol(check_code):
    """检查数组符号"""
    if check_code.count("[") != check_code.count("]"):
        send_error("SyntaxError", "couldn't find ')'")


def check_loop_symbol(codes, index):
    """检查语句块符号"""
    # 何时跳出循环
    break_num = 0
    # 跳出循环后的索引
    ingrammar_index = index
    for add in codes[index:]:
        ingrammar_index += 1
        if "{" in add:
            break_num += 1
        elif "}" in add:
            break_num -= 1
            if break_num == 0:
                break
    if break_num != 0:
        send_error("SyntaxError", "couldn't find '}'")


def check_symbol(oper, check_code):
    """检查符号，例如+，-，*，/等"""
    index = check_code.index(oper)
    try:
        before = check_code[:index]
        later = check_code[index + 1 :]
    except IndexError:
        send_error("SyntaxError", "invalid syntax")
    if len(before) == 0 or len(later) == 0:
        send_error("SyntaxError", "invalid syntax")


def check_string_symbol(symbol, check_code):
    """检查字符串符号"""
    if check_code.count(symbol) != check_code.count(symbol):
        send_error("SyntaxError", "couldn't find '\"'")


def check(codes: list):
    """检查代码语法是否正确

    Args:
        codes (list): 为所有代码
    """

    check_index = 0
    length = len(codes) - 1
    start = TRE.run_index["__main__"]
    TRE.run_index["__main__"] = 0
    while length >= check_index:
        check_code = codes[check_index]
        TRE.run_index["__main__"] = check_index + 1
        if "(" in check_code:
            check_func_symbol(check_code=check_code)
        if "{" in check_code:
            check_loop_symbol(codes, check_index)
        if "[" in check_code:
            check_array_symbol(check_code=check_code)

        if len(check_code) >= 3 and check_code[0] in string:
            check_string_symbol(symbol=check_code[0], check_code=check_code)

        for oper in opers:
            if oper in check_code:
                check_symbol(oper, check_code)
                break
        check_index += 1
    TRE.run_index["__main__"] = start
